<template>
    <div class="typer">
        <div class="typer-content">
            <span
                class="relative flex items-center h-full"
                :style="{ color: color, fontSize: fontSize }"
            >
                <span
                    v-for="(letter, index) in words"
                    :key="index"
                    class="word"
                >{{ letter }}</span>

                <span
                    class="typer-cursor"
                    :style="{
                        background: color,
                        height: cursorHeight
                    }"
                ></span>
            </span>
        </div>
    </div>
</template>

<script setup lang="ts">
const props = defineProps({
    color: {
        type: String,
        default: '#000000'
    },
    fontSize: {
        type: String,
        default: '60px'
    },
    cursorHeight: {
        type: String,
        default: '60px'
    },
    textTips: {
        type: String,
        default: ''
    }
})

const str = ref<string>('')
const order = ref<number>(0)
const words = ref<any>([])
const letters = ref<any>([])

// 输入字符
const write = (i: number) => {
    return () => {
        const L = letters.value.length
        words.value.push(letters.value[i])
        if (i === L - 1) {
            setTimeout(back, 1800)
        }
    }
}

// 擦除字符
const wipe = (i: number) => {
    return () => {
        words.value.pop(letters.value[i])
        if (words.value.length === 0) {
            if (order.value >= props.textTips.length - 1) {
                order.value = 0
            } else {
                order.value++
            }
            setTimeout(begin, 800)
        }
    }
}

// 开始删除效果动画
const back = () => {
    const L = letters.value.length
    for (let i = 0; i < L; i++) {
        setTimeout(wipe(i), i * 100)
    }
}

// 开始输入效果动画
const begin = () => {
    letters.value = str.value.split('')
    for (let i = 0; i < letters.value.length; i++) {
        setTimeout(write(i), i * 200)
    }
}

watch(
    () => props.textTips,
    (newTips: string) => {
        str.value = newTips
    },
    {
        immediate: true
    }
)

onMounted(() => {
    begin()
})
</script>

<style scoped lang="scss">
.typer {
    box-sizing: border-box;
    display: inline-block;
    height: 100%;

    @media screen and (width <= 768px) {
        width: 355px;
    }

    .typer-content {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: center;
        height: 100%;
        font-size: 36px;
        letter-spacing: 2px;
        .word {
            line-height: 1;
        }

        @media screen and (width <= 768px) {
            height: 2em;
            font-size: 26px;
        }
    }

    .typer-cursor {
        display: inline-block;
        width: 3px;

        // height: 28px;
        height: 100%;
        margin-left: 10px;
        background: #333333;
        animation: blink 0.7s infinite;
    }
}

@keyframes blink {
    0% {
        opacity: 1;
    }
    50% {
        opacity: 0;
    }
    100% {
        opacity: 1;
    }
}
</style>
